import { app } from "../../app";
import { menu } from "../../decorator";

const { ccclass, property } = cc._decorator;

interface option {
    timeout?: number,
    responseType?: XMLHttpRequestResponseType,
    headers?: object
}

@ccclass
@menu(__filename)
export default class netHttp extends cc.Component {

    @property
    host: string = '';

    private results = [];
    private requests: Map<XMLHttpRequest, boolean> = new Map();

    public get(api: string, data?: any, option?: option) {
        if (!option) option = {};
        const request = app.lib.http.get({
            url: cc.path.join(this.host, api),
            data: data,
            timeout: option.timeout,
            responseType: option.responseType,
            headers: option.headers
        }, (error, data) => {
            if (error === 'abort') return;
            if (!this.requests.has(request)) return;

            this.requests.delete(request);
            if (this.node && this.node.isValid)
                this.results.push({ method: 'get', api, error, data });
        })
        this.requests.set(request, true);

        return function abort() {
            this.requests.delete(request);
            request.abort();
        }
    }

    public post(api: string, data?: any, option?: option) {
        if (!option) option = {};
        const request = app.lib.http.post({
            url: cc.path.join(this.host, api),
            data: data,
            timeout: option.timeout,
            responseType: option.responseType,
            headers: option.headers
        }, (error, data) => {
            if (error === 'abort') return;
            if (!this.requests.has(request)) return;

            this.requests.delete(request);
            if (this.node && this.node.isValid)
                this.results.push({ method: 'post', api, error, data });
        })
        this.requests.set(request, true);

        return function abort() {
            this.requests.delete(request);
            request.abort();
        }
    }

    public abort() {
        this.requests.forEach(function (a, request) {
            request.abort();
        })
        this.requests.clear();
        this.results.length = 0;
    }

    onDestroy() {
        this.abort();
    }

    update() {
        if (this.results.length) {
            const result = this.results.shift();
            this.node.emit(result.api, result);
        }
    }
}
